/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
(function( $, undefined ) {

$.widget( "theorcs.realtimevalidation", {
	// These options will be used as defaults
    options: { 
    	paramName : null,
    	indicator : null,
    	url : null,
    	delay : 300,
    	minChars : 1,
    	onValidateCallBack : function(content) { alert('You must implement onValidateCallBack '); }
    },
	 
    // Set up the widget
    _create: function() {
    	var self = this;
    	this._initSource();
    	this._onValidateCallBack = eval(self.options.onValidateCallBack);
    	this.element
    		.addClass( "orcs-realtimevalidation-input" )
    		.attr( "realtimevalidation", "off" )
    		.bind( "keypress.realtimevalidation", function( event ) {
    			if( self.options.disabled || self.element.propAttr( "readOnly" ) ){
    				return;
    			}
    			
    			var keyCode = $.ui.keyCode;
    			switch ( event.keyCode ) {
    				default:
    					clearTimeout( self.validating );
						self.validating = setTimeout(function() {
							// only search if the value has changed
							if ( self.term != self.element.val() ) {
								self.validate( null, event );
							}
						}, self.options.delay );
    					break;
    				
    			}
    		});
    	
    	this.response = function() {
			return self._response.apply( self, arguments );
		};
		
    },
    
    // Use the _setOption method to respond to changes to options
    _setOption: function( key, value ) {
	    // In jQuery UI 1.8, you have to manually invoke the _setOption method from the base widget
		$.Widget.prototype._setOption.apply( this, arguments );
		
		if ( key === "url" ) {
			this._initSource();
		}
	
		// In jQuery UI 1.9 and above, you use the _super method instead
		// this._super( "_setOption", key, value );
	
	},
	 
	// Use the destroy method to clean up any modifications your widget has made to the DOM
	destroy: function() {
		// In jQuery UI 1.8, you must invoke the destroy method from the base widget
		$.Widget.prototype.destroy.call( this );
	
	},
	
	/*
	 * Extra Functions
	 */
	
	validate: function(value, event) {
		value = value != null ? value : this.element.val();

		// always save the actual value, not the one passed as an argument
		this.term = this.element.val();

		if ( value.length < this.options.minChars ) {
			return;
		}

		return this._validate( value );
	},
	
	_validate: function( value ) {
		var self = this;
		$("#" + self.options.indicator).show();
		var params = {};
		params[self.options.paramName] = value;
		self.source( params , this.response );
	},
	
	_initSource: function(){
		var self = this,
			url;
		url = self.options.url;
		this.source = function( request, response ){
			self.xhr = $.ajax({
				url: url,
				data: request,
				dataType:"json",
				success: function(data, status){
					response( data );
				},
				error: function(){
					response([]);
				}
			});
		};
	},
	
	_response: function( content ) {
		var self = this;
		this._inform( content );
		$("#" + self.options.indicator).hide();
	},
	
	_inform: function( content ) {
		var self = this;
		this._onValidateCallBack.apply(self, new Array(content));
	}
});

}( jQuery ));